using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using XDL.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XDL.Framework.Particles
{
    /// <summary>
    /// This class collects all the <see cref="ParticleSystem"/> and delegates the game operations (load, update, draw...)
    /// </summary>
    public class ParticleSystemCollection :
        DrawableGameComponent
    {
        ContentManager m_content;
        List<ParticleSystem> m_particleSystems = new List<ParticleSystem>();

        /// <summary>
        /// Creates a particle system collection.
        /// </summary>
        /// <param name="game">Underlying <see cref="Game"/></param>
        /// <param name="content">Content manager.</param>
        public ParticleSystemCollection(Game game, ContentManager content, string[] assetFilenames):
            base(game)
        {
            m_content = content;
            foreach (string assetFilename in assetFilenames)
            {
                ParticleSystem ps = new ParticleSystem(game, m_content, assetFilename);
                Add(assetFilename, ps);
            }
        }

        /// <summary>
        /// Add an existing particle system.
        /// </summary>
        /// <param name="particleSystemName">Unique identifier</param>
        /// <param name="ps"><see cref="ParticleSystem"/> instance.</param>
        public void Add(string particleSystemName, ParticleSystem ps)
        {
            GameServices.AddService(particleSystemName, ps);
            m_particleSystems.Add(ps);
        }

        public override void Initialize()
        {
            // 
            foreach (ParticleSystem it in m_particleSystems)
                it.Initialize();
        }

        /// <summary>
        /// Removes all active particle systems.
        /// </summary>
        public void Clear()
        {
            foreach (ParticleSystem it in m_particleSystems)
                it.Clear();
        }

        /// <summary>
        /// Sets the camera view and projection matrices that will be used to draw this particle system.
        /// </summary>
        /// <param name="view">View matrix</param>
        /// <param name="projection">Projection matrix</param>
        public void SetCamera(Matrix view, Matrix projection)
        {
            foreach (ParticleSystem it in m_particleSystems)
                it.SetCamera(view, projection);
        }

        /// <summary>
        /// Sets the viewport (mostly used to adjust particle aspect ratio)
        /// </summary>
        /// <param name="vport">Current viewport</param>
        public void SetViewport(Viewport vport)
        {
            foreach (ParticleSystem it in m_particleSystems)
                it.SetViewport(vport);
        }

        /// <summary>
        /// Updates the <see cref="ParticleSystem"/>.
        /// </summary>
        /// <param name="gameTime">Game time</param>
        public override void Update(GameTime gameTime)
        {
            foreach (ParticleSystem it in m_particleSystems)
                it.Update(gameTime);
        }

        /// <summary>
        /// Draw the particle systems.
        /// </summary>
        /// <param name="gameTime">Game time</param>
        public override void Draw(GameTime gameTime)
        {
            foreach (ParticleSystem it in m_particleSystems)
                it.Draw(gameTime);
        }
    }
}
